import os
import librosa
from multiprocessing import Process, Queue
import numpy as np

# 通过Process类构建子进程进行并行计算音高和声强，并将结果保存到文件中（一个声音一个文件）
def process_sound_files(file_name):
    # 计算音高和声强
    y, sr = librosa.load(file_name)
    f01 = librosa.yin(y, fmin=librosa.note_to_hz('C1'), fmax=librosa.note_to_hz('C7'))
    db = librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max)

    # 保存结果到文件
    result_file_name = r"C:\Users\User\Desktop\code\pycode\lab11\results.txt"
    with open(result_file_name, "a") as f:
        f.write(f"音高为: {f01} Hz \n声强为: {db}\n")

# 通过继承Process类构建子进程进行并行计算音高和声强，并将结果保存到文件中（一个声音一个文件）
class SoundFileProcessor(Process):
    def __init__(self, sound_file, result_queue):
        super(SoundFileProcessor, self).__init__()
        self.sound_file = sound_file
        self.result_queue = result_queue

    def run(self):
        y, sr = librosa.load(self.sound_file)
        f01 = librosa.yin(y, fmin=librosa.note_to_hz('C1'), fmax=librosa.note_to_hz('C7'))
        db = librosa.amplitude_to_db(np.abs(librosa.stft(y)), ref=np.max)

        # 保存结果到队列
        result = f"{os.path.basename(self.sound_file)} 音高为: {f01} Hz，\n声强为: {db}\n"
        self.result_queue.put(result)

# 主进程启动子进程，并分发参数（声音文件名）
if __name__ == "__main__":
    # 获取声音数据目录下所有声音文件的列表
    sound_dir = r'C:\Users\User\Desktop\code\pycode\lab11\music1'
    sound_files = [os.path.join(sound_dir, file_name) 
                for file_name in os.listdir(sound_dir) 
                if file_name.endswith(".mp3")]
    # 方法二：继承Process类
    result_queue = Queue()
    processes = []
    for sound_file in sound_files:
        processor = SoundFileProcessor(sound_file=sound_file, result_queue=result_queue)
        processes.append(processor)
        processor.start()

    for process in processes:
        process.join()

        
    # 将计算结果从队列中取出并保存到文件中
    with open("results.txt", "a") as f:
        while not result_queue.empty():
            result = result_queue.get()
            f.write(result + "\n")
    #print(sound_files)
    #process_sound_files(sound_files[0])
"""# 方法一：使用Process类
    processes = []
    for i in range(3):
        process = Process(target=process_sound_files, args=(sound_files[i], ))
        processes.append(process)
        process.start()

    for process in processes:
        process.join()
"""    
    
